{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(array([[ 2.55025 , -1.274323],\n",
       "        [ 2.345839, -0.398576],\n",
       "        [ 1.961587, -1.238267],\n",
       "        [ 1.56649 , -3.583607],\n",
       "        [-0.150944, -1.745203]]),\n",
       " array([-24.897896, -23.759634, -26.591775, -32.467744, -33.943239]))"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "\n",
    "#加载数据\n",
    "def load_data():\n",
    "    with open('多变量线性数据.txt') as fr:\n",
    "        lines = fr.readlines()\n",
    "\n",
    "    x = np.empty((len(lines), 2), dtype=float)\n",
    "    y = np.empty(len(lines), dtype=float)\n",
    "\n",
    "    for i in range(len(lines)):\n",
    "        line = lines[i].strip().split(',')\n",
    "        x[i] = line[:2]\n",
    "        y[i] = line[2]\n",
    "\n",
    "    return x, y\n",
    "\n",
    "\n",
    "x, y = load_data()\n",
    "x[:5], y[:5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "#常量\n",
    "N = len(x)\n",
    "w = np.array([1, 1], dtype=float)\n",
    "b = 0.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1.275927, -24.897896)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#预测函数\n",
    "def predict(x):\n",
    "    return w.dot(x) + b\n",
    "\n",
    "\n",
    "predict(x[0]), y[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "158672.1811617043"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#求loss,就是简单的做差求平方和\n",
    "def get_loss():\n",
    "    loss = 0\n",
    "    for i in range(N):\n",
    "        loss += np.power(predict(x[i]) - y[i], 2)\n",
    "    return loss\n",
    "\n",
    "\n",
    "get_loss()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(21052.372189576075, -22746.83249711943, 11223.409115999997)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#求w0梯度\n",
    "#为了简化,这里假设只有两个样本\n",
    "#loss = (w0*x00 + w1*x01 + b - y0)^2 + (w0*x10 + w1*x11 + b - y1)^2\n",
    "#定义z1 = w1*x01 + b - y0\n",
    "#定义z2 = w1*x11 + b - y1\n",
    "#带入得\n",
    "#loss = (w0*x00 + z1)^2 + (w0*x10 + z2)^2\n",
    "#平方和公式\n",
    "#loss = w0^2*x00^2 + z1^2 + 2*w0*x00*z1 + w0^2*x10^2 + z2^2 + 2*w0*x10*z2\n",
    "#求导数\n",
    "#d_loss/d_w0 = 2*w0*x00^2 + 2*x00*z1 + 2*w0*x10^2 + 2*x10*z2\n",
    "#提取公因式\n",
    "#d_loss/d_w0 = 2*[w0*(x00^2 + x10^2) + x00*z1 + x10*z2]\n",
    "#整理成一般形式\n",
    "#d_loss/d_w0 = 2*[w0*sigma(xi0^2) + sigma(xi0*(w1*xi1 + b - yi))]\n",
    "\n",
    "#同理可得\n",
    "#d_loss/d_w1 = 2*[w1*sigma(xi1^2) + sigma(xi1*(w0*xi0 + b - yi))]\n",
    "\n",
    "#求b梯度\n",
    "#为了简化,这里假设只有两个样本\n",
    "#loss = (w0*x00 + w1*x01 - y1 + b)^2 + (w0*x10 + w1*x11 - y2 + b)^2\n",
    "#定义z1 = w0*x00 + w1*x01 - y1\n",
    "#定义z2 = w0*x10 + w1*x11 - y2\n",
    "#带入得\n",
    "#loss = (z1 + b)^2 + (z2 + b)^2\n",
    "#平方和公式\n",
    "#loss = z1^2 + b^2 + 2*z1*b + z2^2 + b^2 + 2*z2*b\n",
    "#求导数\n",
    "#d_loss/d_b = 2*b + 2*z1 + 2*b + 2*z2\n",
    "#提取公因式\n",
    "#d_loss/d_b = 2*[2*b + z1 + z2]\n",
    "#整理成一般形式\n",
    "#d_loss/d_b = 2*[N*b + sigma(w0*xi0 + w1*xi1 - yi)]\n",
    "def get_gradient():\n",
    "\n",
    "    #d_loss/d_w0 = 2*[w0*sigma(xi0^2) + sigma(xi0*(w1*xi1 + b - yi))]\n",
    "    sigma1 = 0\n",
    "    sigma2 = 0\n",
    "    for i in range(N):\n",
    "        sigma1 += np.power(x[i, 0], 2)\n",
    "        sigma2 += x[i, 0] * (w[1] * x[i, 1] + b - y[i])\n",
    "    d_w0 = 2 * (w[0] * sigma1 + sigma2)\n",
    "\n",
    "    #d_loss/d_w1 = 2*[w1*sigma(xi1^2) + sigma(xi1*(w0*xi0 + b - yi))]\n",
    "    sigma1 = 0\n",
    "    sigma2 = 0\n",
    "    for i in range(N):\n",
    "        sigma1 += np.power(x[i, 1], 2)\n",
    "        sigma2 += x[i, 1] * (w[0] * x[i, 0] + b - y[i])\n",
    "    d_w1 = 2 * (w[1] * sigma1 + sigma2)\n",
    "\n",
    "    #d_loss/d_b = 2*[N*b + sigma(w0*xi0 + w1*xi1 - yi)]\n",
    "    z = 0\n",
    "    for i in range(N):\n",
    "        z += w[0] * x[i, 0] + w[1] * x[i, 1] - y[i]\n",
    "    d_b = 2 * (N * b + z)\n",
    "\n",
    "    return d_w0, d_w1, d_b\n",
    "\n",
    "\n",
    "get_gradient()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "70653.16948951509\n",
      "7258.654061605819\n",
      "3431.812705911125\n",
      "1622.527027100541\n",
      "767.1146940557143\n",
      "362.68422282486324\n",
      "171.4735052077762\n",
      "81.07097341938362\n",
      "38.32955256389769\n",
      "18.121832485638066\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(array([2.84379987, 2.14201554]), -29.35406355651145)"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#慢慢调整w和b\n",
    "for i in range(1000):\n",
    "    _w0, _w1, _b = get_gradient()\n",
    "    w[0] -= _w0 * 1e-4\n",
    "    w[1] -= _w1 * 1e-4\n",
    "    b -= _b * 1e-4\n",
    "\n",
    "    if i % 100 == 0:\n",
    "        print(get_loss())\n",
    "\n",
    "w, b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "-24.831282619826084 -24.897896\n",
      "-23.536722910696515 -23.759634\n",
      "-26.428089867508383 -26.591775\n",
      "-32.575421390074226 -32.467744\n",
      "-33.52157003030706 -33.943239\n",
      "-22.930002564459187 -22.886769\n",
      "-32.224163111877026 -32.595698\n",
      "-32.995233028195486 -32.961657\n",
      "-32.29565809467522 -32.260963\n",
      "-22.762132234313285 -22.91686\n",
      "-22.952385485754856 -23.224347\n",
      "-26.920804668165367 -26.761884\n",
      "-26.731380109313996 -26.83519\n",
      "-28.073917422331743 -28.29683\n",
      "-22.83938708753162 -22.700174\n",
      "-25.317872586210964 -25.399424\n",
      "-26.060577273472177 -26.365\n",
      "-24.427930960115386 -24.191492\n",
      "-29.580000273310667 -29.502944\n",
      "-24.476281757200464 -24.260812\n",
      "-27.49024026852517 -27.233203\n",
      "-31.354914235530764 -31.615989\n",
      "-28.285332519101694 -28.340193\n",
      "-24.721963403436867 -24.714052\n",
      "-32.73327434705432 -32.626654\n",
      "-24.53233285724264 -24.617518\n",
      "-27.17966101003199 -27.533744\n",
      "-29.086309286670755 -29.187444\n",
      "-22.771686982725065 -22.808779\n",
      "-24.10143520585138 -24.02964\n",
      "-25.960593254588364 -25.882721\n",
      "-20.633579790954116 -20.574579\n",
      "-37.41610765346236 -37.785277\n",
      "-29.125228573901627 -29.384143\n",
      "-28.592256936816263 -28.87989\n",
      "-29.6359236967472 -29.811187\n",
      "-27.177138656455107 -27.315989\n",
      "-22.29142638506562 -22.345454\n",
      "-22.850314227220117 -23.006784\n",
      "-26.98721868525984 -27.018666\n",
      "-28.420806493909446 -29.114606\n",
      "-24.096362639358723 -24.050712\n",
      "-28.8778555080896 -28.965701\n",
      "-28.72821736340316 -28.807204\n",
      "-26.96817065113113 -27.172519\n",
      "-24.81886803208947 -24.526498\n",
      "-31.275172326176556 -31.034457\n",
      "-35.30543359021287 -35.131266\n",
      "-26.461193396519374 -26.359204\n",
      "-24.914183348058184 -25.152534\n",
      "-36.536764214204595 -36.60391\n",
      "-26.76382523458647 -26.764776\n",
      "-29.684629171518505 -29.77079\n",
      "-28.646127426365883 -28.790259\n",
      "-30.535826849614025 -30.883915\n",
      "-24.603012193550413 -24.488038\n",
      "-25.9529879853362 -25.877444\n",
      "-22.69822877264867 -22.660873\n",
      "-22.026806520560427 -22.095426\n",
      "-23.44985420469076 -23.373639\n",
      "-31.14452271557857 -31.096975\n",
      "-31.24808655322456 -31.193845\n",
      "-33.97603104250118 -34.145095\n",
      "-31.779881566798288 -32.23144\n",
      "-30.91547359582804 -30.990845\n",
      "-26.869633097273983 -26.665352\n",
      "-30.10994383076009 -30.214546\n",
      "-27.45706896151331 -27.82455\n",
      "-28.427691449964062 -28.595442\n",
      "-35.94850420449792 -36.024308\n",
      "-28.555673370655327 -28.867871\n",
      "-32.22047244625751 -32.466004\n",
      "-28.422070647381734 -28.362192\n",
      "-28.850915139252546 -29.193895\n",
      "-28.448705171774403 -28.363757\n",
      "-27.15303797917506 -27.181018\n",
      "-24.776887879553747 -24.557624\n",
      "-32.094144996903246 -32.281904\n",
      "-30.137237398412488 -30.176946\n",
      "-25.660366263431424 -25.772576\n",
      "-34.48453805028864 -34.452661\n",
      "-28.517164313799174 -28.351894\n",
      "-26.769605216621855 -26.562994\n",
      "-32.49196890087144 -32.547563\n",
      "-25.232094003792696 -24.94148\n",
      "-24.45625649960035 -24.762602\n",
      "-28.109710105137115 -27.859265\n",
      "-23.887480534891836 -24.025429\n",
      "-22.703893348456923 -22.863637\n",
      "-27.10032841816881 -27.154449\n",
      "-32.861229924274994 -32.710551\n",
      "-24.144200588937494 -24.14208\n",
      "-26.10137115721762 -26.033732\n",
      "-23.25826015480844 -23.284463\n",
      "-21.379505756337128 -21.250875\n",
      "-29.315471166547763 -29.64435\n",
      "-21.053887990356152 -21.146349\n",
      "-23.933588455967403 -23.794467\n",
      "-31.62827488546358 -31.320567\n",
      "-36.7352939457745 -37.196242\n",
      "-23.114812276414927 -22.901027\n",
      "-29.33688710567265 -29.516081\n",
      "-29.517959523261837 -29.695863\n",
      "-29.08445453492734 -29.138859\n",
      "-23.462713221845462 -23.355301\n",
      "-24.60621189641759 -24.90467\n",
      "-24.948473085747995 -25.087982\n",
      "-27.851232995068525 -27.915039\n",
      "-23.46202445174438 -23.885224\n",
      "-24.29570745251263 -24.369527\n",
      "-22.05296106654106 -22.023272\n",
      "-34.40513810398484 -34.756981\n",
      "-36.69792448136647 -36.805424\n",
      "-30.298291799063676 -30.122588\n",
      "-25.11538897593153 -25.425166\n",
      "-34.39097646191881 -34.42282\n",
      "-25.95736619203637 -25.974489\n",
      "-26.176756205263324 -26.526482\n",
      "-30.58231683366933 -30.523149\n",
      "-20.28738342751481 -20.177964\n",
      "-30.372061700445336 -30.361714\n",
      "-18.976183527609223 -19.365356\n",
      "-33.183329557517204 -32.940343\n",
      "-21.664511659365964 -21.980284\n",
      "-23.518508242826087 -23.500859\n",
      "-35.63708123201874 -35.604958\n",
      "-27.410693397006185 -27.469822\n",
      "-25.88834884208311 -25.805073\n",
      "-37.38652323957595 -37.574153\n",
      "-33.65031672685154 -33.76968\n",
      "-24.90806501136546 -24.689869\n",
      "-28.329419752635935 -28.002767\n",
      "-24.173191800907816 -24.005383\n",
      "-25.042509845121756 -25.291998\n",
      "-29.88765946734868 -29.91651\n",
      "-31.276897088572984 -31.197088\n",
      "-24.143129529587178 -24.31428\n",
      "-22.388195940514265 -22.293879\n",
      "-29.759029949458466 -29.629092\n",
      "-30.36834970812211 -30.519177\n",
      "-31.13528608341608 -31.772269\n",
      "-30.10536124011884 -30.113308\n",
      "-26.53325191412177 -26.160162\n",
      "-31.067583735819493 -31.144393\n",
      "-27.749888971367277 -27.830412\n",
      "-30.168975107407945 -30.300173\n",
      "-33.91839328423337 -34.081622\n",
      "-32.75004475486157 -32.507768\n",
      "-28.76926596855889 -28.443651\n",
      "-27.287029528726283 -27.31189\n",
      "-27.58065078814028 -27.668376\n",
      "-27.150769064665823 -27.048838\n",
      "-28.847354534252116 -28.900829\n",
      "-35.35190824093713 -35.139714\n",
      "-24.056379429505455 -23.943962\n",
      "-22.061746688820087 -22.289861\n",
      "-24.73187825617471 -24.697077\n",
      "-35.46950098556859 -35.796166\n",
      "-25.99421144242295 -25.666207\n",
      "-25.067485946488596 -25.161309\n",
      "-30.573433807180308 -30.866572\n",
      "-30.74514099961933 -30.654283\n",
      "-28.391540953567173 -28.538393\n",
      "-23.71954484069495 -23.476155\n",
      "-24.20812312541982 -24.115886\n",
      "-20.302451789227337 -20.408436\n",
      "-24.577561537189407 -24.546129\n",
      "-21.478767807008865 -21.309363\n",
      "-30.439210005367187 -30.334568\n",
      "-30.366589905523682 -30.534206\n",
      "-37.44487198054284 -37.534605\n",
      "-29.940582867714625 -29.973863\n",
      "-31.23401746525105 -31.195785\n",
      "-22.712772299835517 -23.033678\n",
      "-31.760962965434878 -31.693342\n",
      "-31.798880751163985 -31.817053\n",
      "-33.4283147068802 -33.418762\n",
      "-20.341818202337585 -20.5956\n",
      "-31.608834870404365 -31.822448\n",
      "-35.20373699718795 -35.554906\n",
      "-27.03744519391444 -27.342615\n",
      "-23.40553692413157 -23.485852\n",
      "-28.606550242759425 -29.12834\n",
      "-29.94948440808195 -30.002598\n",
      "-29.023114755996204 -29.240391\n",
      "-29.044518556936346 -29.078613\n",
      "-33.1827900993253 -33.055663\n",
      "-30.02231299618495 -30.104794\n",
      "-27.213546015240972 -26.767678\n",
      "-29.902721283312715 -30.093786\n",
      "-26.9020340372165 -26.906383\n",
      "-32.89859788933647 -33.024109\n",
      "-28.067567862455622 -28.214158\n",
      "-29.66698111892326 -29.833389\n",
      "-30.838124482709727 -31.29836\n",
      "-27.51735428906711 -27.698624\n",
      "-27.829928368336315 -28.050526\n",
      "-28.04699537360792 -28.119836\n",
      "-32.025702736750986 -32.048623\n",
      "-28.225664652993164 -28.632448\n"
     ]
    }
   ],
   "source": [
    "for i in range(N):\n",
    "    pred = predict(x[i])\n",
    "    print(pred, y[i])"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
